package uml.view.factory;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.border.Border;

import net.miginfocom.swing.MigLayout;
import uml.eventsystem.KeyHandler;
import uml.eventsystem.MouseHandler;
import uml.eventsystem.events.UMLEventId;
import uml.util.UMLConstants;
import uml.util.UMLUtility;
import uml.util.listeners.DragListener;
import uml.view.ClassFormatter_View;
import uml.view.UMLContainerView;

/**
 * A factory used to create UML objects to be placed in a View. Users only need 
 * to handle UMLContainerViews; the factory will decide how to create the specified 
 * object the user requests.  
 * 
 * @author Neil Obetz
 *
 */

public final class ContainerFactory
{
	public static UMLContainerView createContainer(UMLEventId event)
	{
		UMLContainerView container = null;
		switch(event)
		{
			case MAKE_ABSTRACT:
				container = createContainer (UMLConstants.ABSTRACT_LAYOUT_PARAMS, UMLConstants.ABSTRACT_BORDER, UMLConstants.ABSTRACT_DEFAULT_TEXT, UMLConstants.ABSTRACT_BACKGROUND, UMLConstants.ABSTRACT_LAYER);
				break;
			case MAKE_SIMPLE:
				container = createContainer (UMLConstants.SIMPLE_LAYOUT_PARAMS, UMLConstants.SIMPLE_BORDER, UMLConstants.SIMPLE_DEFAULT_TEXT, UMLConstants.SIMPLE_BACKGROUND, UMLConstants.SIMPLE_LAYER);
				break;
			case MAKE_SIMPLE_ABSTRACT:
				container = createContainer (UMLConstants.SIMPLE_ABSTRACT_LAYOUT_PARAMS, UMLConstants.SIMPLE_ABSTRACT_BORDER, UMLConstants.SIMPLE_ABSTRACT_DEFAULT_TEXT, UMLConstants.SIMPLE_ABSTRACT_BACKGROUND, UMLConstants.SIMPLE_ABSTRACT_LAYER);
				break;
			case MAKE_CLASS:
				container = createContainer(UMLConstants.CLASS_LAYOUT_PARAMS, UMLConstants.CLASS_BORDER, UMLConstants.CLASS_DEFAULT_TEXT, UMLConstants.CLASS_BACKGROUND, UMLConstants.CLASS_LAYER);
				break;
			case MAKE_INTERFACE:
				container = createCircleInterfaceView();//createContainer(UMLConstants.INTERFACE_LAYOUT_PARAMS, UMLConstants.INTERFACE_BORDER, UMLConstants.INTERFACE_DEFAULT_TEXT);
				break;
			case MAKE_NOTE:
				container = createContainer(UMLConstants.NOTE_LAYOUT_PARAMS, UMLConstants.NOTE_BORDER, UMLConstants.NOTE_DEFAULT_TEXT, UMLConstants.NOTE_BACKGROUND, UMLConstants.NOTE_LAYER);
				break;
			case MAKE_PACKAGE:
				container = createPackageView();//createContainer(UMLConstants.PACKAGE_LAYOUT_PARAMS, UMLConstants.PACKAGE_BORDER, UMLConstants.PACKAGE_DEFAULT_TEXT);
				break;
			default:
				break;
		}
		container.setEventId(event);
		return container;
	}
	public static UMLContainerView createContainer(UMLEventId event, String[] text)
	{
		UMLContainerView container = null;
		switch(event)
		{
			case MAKE_ABSTRACT:
				container = createContainer (UMLConstants.ABSTRACT_LAYOUT_PARAMS, UMLConstants.ABSTRACT_BORDER, text, UMLConstants.ABSTRACT_BACKGROUND, UMLConstants.ABSTRACT_LAYER);
				break;
			case MAKE_SIMPLE:
				container = createContainer (UMLConstants.SIMPLE_LAYOUT_PARAMS, UMLConstants.SIMPLE_BORDER, text, UMLConstants.SIMPLE_BACKGROUND, UMLConstants.SIMPLE_LAYER);
				break;
			case MAKE_SIMPLE_ABSTRACT:
				container = createContainer (UMLConstants.SIMPLE_ABSTRACT_LAYOUT_PARAMS, UMLConstants.SIMPLE_ABSTRACT_BORDER, text, UMLConstants.SIMPLE_ABSTRACT_BACKGROUND, UMLConstants.SIMPLE_ABSTRACT_LAYER);
				break;
			case MAKE_CLASS:
				container = createContainer(UMLConstants.CLASS_LAYOUT_PARAMS, UMLConstants.CLASS_BORDER, text, UMLConstants.CLASS_BACKGROUND, UMLConstants.CLASS_LAYER);
				break;
			case MAKE_INTERFACE:
				container = createCircleInterfaceView();//createContainer(UMLConstants.INTERFACE_LAYOUT_PARAMS, UMLConstants.INTERFACE_BORDER, UMLConstants.INTERFACE_DEFAULT_TEXT);
				break;
			case MAKE_NOTE:
				container = createContainer(UMLConstants.NOTE_LAYOUT_PARAMS, UMLConstants.NOTE_BORDER, text, UMLConstants.NOTE_BACKGROUND, UMLConstants.NOTE_LAYER);
				break;
			case MAKE_PACKAGE:
				container = createPackageView();//createContainer(UMLConstants.PACKAGE_LAYOUT_PARAMS, UMLConstants.PACKAGE_BORDER, UMLConstants.PACKAGE_DEFAULT_TEXT);
				break;
			default:
				break;
		}
		if (container != null) 
		  container.setEventId(event);
		return container;
	}
	private static UMLContainerView createContainer(String[] layoutParams, Border border, String[] defaultText, Color backgroundColor, Integer layer)
	{
		UMLContainerView container = new UMLContainerView();
		setUpLayout(container, layoutParams);
		addJTextAreas(container, defaultText, true);
		container.setBorder(border);
		container.setInactiveBorder(border);
		addListeners(container);
		container.setBackground(backgroundColor);
		container.setOpaque(false);
		container.setLayer(layer);
		return container;
	}

	private static void addJTextAreas(UMLContainerView container, String[] defaultText, boolean withDividers) 
	{
		boolean loopedOneTime = false;//for getting dividers in the right spots
		for(String text : defaultText)
		{
			if(withDividers & loopedOneTime)
				container.add (new JSeparator (), "growx, wrap");
			JTextArea textArea = new JTextArea(text);
			UMLUtility.removeMouseListeners(textArea);
			textArea.addMouseListener(container);
			textArea.addMouseMotionListener(container);
			textArea.setBackground(UMLConstants.TEXTAREA_COLOR);
			container.add(textArea);
			textArea.setOpaque(false);
			loopedOneTime = true;
		}
	}
	 /**
	  * Adds support for <tt>MouseHandler</tt> and <tt>KeyHandler</tt>
	  * @param container
	  */
	private static void addListeners(UMLContainerView container)
	{
		container.addMouseListener(MouseHandler.getMouseHandler());
		container.addMouseMotionListener(MouseHandler.getMouseHandler());
	}
	/**
	 * Set container with a MigLayout using the parameters layoutParam
	 * @param container
	 * @param layoutParams
	 */
	private static void setUpLayout(UMLContainerView container, String[] layoutParams)
	{
		MigLayout layout = new MigLayout(layoutParams[0], layoutParams[1], layoutParams[2]);
		container.setLayout(layout);
	}
	
	/**
	 * Creates a default alternate circle style UML interface.
	 * @return the circle style interface.
	 */
	
	public static UMLContainerView createCircleInterfaceView ()
	{
		UMLContainerView circleInterface = new UMLContainerView ();
		circleInterface.setLayout (new MigLayout ("wrap1, filly", "[align center]"));
		circleInterface.setBackground (UMLConstants.INTERFACE_BACKGROUND);
		circleInterface.setSize (UMLConstants.NOTE_SIZE);
		
		JLabel circleLabel = new JLabel ();

		circleLabel.setBackground (circleInterface.getBackground ());
		BufferedImage iconImage = new BufferedImage(25,25,BufferedImage.TYPE_INT_RGB);
		Graphics2D circle = iconImage.createGraphics();
		
		//circle.setColor (Color.black);
		circle.fillRect (0, 0, iconImage.getWidth (), iconImage.getHeight ());
		circle.setColor (Color.BLACK);
		circle.drawOval ((iconImage.getWidth ()-20)/2, (iconImage.getHeight ()-20)/2, 20, 20);
		circle.setBackground(UMLConstants.INTERFACE_BACKGROUND);
		circleLabel.print(circle);
		ImageIcon circleIcon = new ImageIcon(iconImage);
		circleLabel.setIcon (circleIcon);
		circleInterface.add (circleLabel, "wrap");
		addJTextAreas(circleInterface, UMLConstants.INTERFACE_DEFAULT_TEXT, true);
		ClassFormatter_View formatter = new ClassFormatter_View ();
		formatter.setContainer (circleInterface);
		formatter.setFontItalic ();
		addListeners (circleInterface);
		circleInterface.setOpaque(false);
		circleInterface.setLayer (UMLConstants.INTERFACE_LAYER);
		circleInterface.setInactiveBorder(null);
		return (circleInterface);
	}
	
	/**
	 * Creates a package view UML container object and returns it to the user.
	 * @return the package view
	 */
	
	public static UMLContainerView createPackageView ()
	{
		Border sharedBorder = UMLConstants.PACKAGE_BORDER;
		
		JPanel tab = new JPanel ();
		tab.setBackground (UMLConstants.PACKAGE_COLOR);
		
		JTextArea nameTab = new JTextArea("Package");
		nameTab.setOpaque (false);
		UMLUtility.removeMouseListeners(nameTab);
		
		tab.add (nameTab);
		tab.setBackground (UMLConstants.PACKAGE_COLOR);
		tab.setBorder (sharedBorder);
		UMLUtility.removeMouseListeners (tab);
		
		JPanel body = new JPanel ();
		body.setBackground (UMLConstants.PACKAGE_COLOR);
		body.setBorder (sharedBorder);
		UMLUtility.removeMouseListeners (body);
		
		UMLContainerView packageView = new UMLContainerView ();
		packageView.setLayout (new MigLayout ("wrap 1, fillx", "1[left center]1", "0[]0"));
		tab.addMouseListener (packageView);
		tab.addMouseMotionListener (packageView);
		packageView.add (tab, "wrap, height 20, width 80");
		body.addMouseListener (packageView);
		body.addMouseMotionListener (packageView);
		packageView.add (body, "height 200, width 400, growy, growy");
		
		packageView.setOpaque (false);
		packageView.setLayer (UMLConstants.PACKAGE_LAYER);
		packageView.setBorder(null);
		addListeners (packageView);
		
		return (packageView);
	}
}
